package org.cos.generation.plugin;

/* Used for encryption.
import java.io.File;
import org.cos.generation.util.encrypt.Encryptor;
*/
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import org.cos.generation.ast.CoSASTAnalyzer;
import org.cos.generation.util.info.ClassInfo;
import org.cos.generation.util.info.SRMT;
import org.cos.generation.util.xml.ModelOutput;
import org.cos.generation.util.xml.SRMTReader;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;

public class GenerateModelAction extends AbstractHandler {

	public Object execute(ExecutionEvent event) throws ExecutionException {
		IStructuredSelection selection = (IStructuredSelection) HandlerUtil
			.getActiveMenuSelection(event);
		Object firstElement = selection.getFirstElement();
		
		if (firstElement instanceof IJavaProject) {
			try {
				// Get the project.
				IJavaProject javaProject = (IJavaProject)firstElement;
				IProject project = javaProject.getProject();
				
				// Get all .java files in the src folder,
				// Then put them into compilation unit list.
				IFolder srcFolder = project.getFolder("src");
				List<ICompilationUnit> cuList = new LinkedList<ICompilationUnit>();
			
				
				Stack<IFolder> folderStack = new Stack<IFolder>();
				folderStack.push(srcFolder);
				while (!folderStack.isEmpty()) {
					IFolder folder = folderStack.pop();
					IResource resources[] = folder.members();
					for (IResource res : resources) {
						switch (res.getType()) {
						case IResource.FOLDER:
							folderStack.push((IFolder)res);
							break;
						case IResource.FILE:
							IFile file = (IFile)res;
							String ext = file.getFileExtension();
							if (ext != null && ext.equals("java")) {
								ICompilationUnit cu = 
										(ICompilationUnit)JavaCore.create(file);
								cuList.add(cu);
							}
							break;
						}
					}
				}
						
				project.build(6, null);
				
				generate(cuList, project);
				
				MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
						"成功", project.getName() + "项目的模型产生成功");
				
			
			} catch (CoreException e) {
				e.printStackTrace();
			}catch (Exception e) {
				e.printStackTrace();
				MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
						"失败", "模型产生失败\n信息：" + e.getMessage());		
			}
		} else if (firstElement instanceof ICompilationUnit) {
			try {
				// Get the project.
				ICompilationUnit cu = (ICompilationUnit)firstElement;
				IProject project = cu.getResource().getProject();
				
				List<ICompilationUnit> cuList = new ArrayList<ICompilationUnit>(1);
				
				cuList.add(cu);
				
				generate(cuList, project);
				
				MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
						"成功", cu.getResource().getName() + "文件的模型产生成功");
			} catch (Exception e) {
				MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
						"失败", "模型产生失败\n信息：" + e.getMessage());
				e.printStackTrace();
			}
		} else {
			MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
					"提示", "请选择一个Java项目或Java文件");
		}
		return null;
	}
	
	public void generate(List<ICompilationUnit> cuList, IProject project) throws Exception {
		// Initialize the SRMT.
		InputStream inputStream = getClass().getResourceAsStream("/SRMT.xml");
		if (inputStream != null) {
			SRMT.init(SRMTReader.read(inputStream));
		} else {
			throw new IOException();
		}
		// Analyze the compilation units in the list.
		List<ClassInfo> classInfoList = CoSASTAnalyzer.analysis(cuList);
		
		// Clear the SRMT.
		SRMT.clear();
		
		// Get the project path.
		String projectPath = project.getLocation().toString();
		projectPath.replace("/", "//");
		
		// Output the model file.
		ModelOutput xmlGenerator = new ModelOutput();
		xmlGenerator.generate(projectPath, classInfoList);
		
		/* Output the model file and encrypt the model file.
		List<File> fileList = xmlGenerator.generate(projectPath, classInfoList);
		Encryptor.encrypt(fileList);
		*/
	}

}
